<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>Creating a New Platform for TinyOS 2.x</title>
<meta name="author" content="Martin Leopold" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2009-02-03 23:07:32 $
:version: $Revision: 1.2 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/
body {
  font-family: Times;
  font-size: 16px;
}

.first {
  margin-top: 0 ! important }

.last {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1 {
  font-family: Arial, sans-serif;
  font-size: 20px;
}

h1.title {
 text-align: center;
 font-size: 32px;
}

h2 {
 font-size: 16px;
 font-family: Arial, sans-serif;
}

h2.subtitle {
  text-align: center }

h3 {
 font-size: 12px;
 font-family: Arial, sans-serif;
}

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee;
  border-color: #000000;
  border-width: thin; 
  font-size: 14px
}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em;
}

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap;
  }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {}

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="creating-a-new-platform-for-tinyos-2-x">
<h1 class="title">Creating a New Platform for TinyOS 2.x</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">131</td>
</tr>
<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">TinyOS 8051 Working Group</td>
</tr>
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Informational</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
<td>Draft</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Martin Leopold</td></tr>
<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">6-Nov-2007</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">6-Nov-2007</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
</tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo is informational. It will hopefully be a basis for
discussions and suggestions for improvements.  Distribution of this
memo is unlimited.  This memo is in full compliance with TEP 1.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id4" id="abstract" name="abstract">Abstract</a></h1>
<p>The purpose of this TEP is to provide on overview of how to build a
new TinyOS 2 platform. While the purpose of most TEPs is to describe
TinyOS 2 entities, we will present concrete suggestions on how to
implement a new TinyOS 2 platform. We will use examples and briefly
cover the relevant TEPs to present a platform that adheres to the
current TinyOS standards. We will not cover the TEPs in detail, but to
the full text of each TEP for further information.</p>
<p>This TEP will go through the tool chain setup and the most basic
components for a functional TinyOS platform. We consider only TinyOS
version 2.x (from now on TinyOS).</p>
<p>Before venturing on this quest we will take a diversion and introduce
general TinyOS 2 concepts and terminology (Section 1), readers
familiar to TinyOS 2 can skip this section. This document will
introduce the TinyOS 2 platform (Section 2) and describes the 3
elements that make up a platform: the tool chain (Section 3) the
platform definitions (Section 4) and the chips definitions (Section
5).</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id5" id="table-of-content" name="table-of-content">Table of Content</a></h1>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#abstract" id="id4" name="id4">Abstract</a></li>
<li><a class="reference" href="#table-of-content" id="id5" name="id5">Table of Content</a></li>
<li><a class="reference" href="#tinyos-overview" id="id6" name="id6">1. TinyOS Overview</a><ul>
<li><a class="reference" href="#tinyos-2-architecture" id="id7" name="id7">1.1 TinyOS 2 architecture</a></li>
<li><a class="reference" href="#tinyos-contrib" id="id8" name="id8">1.2 TinyOS Contrib</a></li>
</ul>
</li>
<li><a class="reference" href="#a-tinyos-platform" id="id9" name="id9">2. A TinyOS Platform</a><ul>
<li><a class="reference" href="#a-new-platform" id="id10" name="id10">2.1 A New Platform</a></li>
<li><a class="reference" href="#the-chips" id="id11" name="id11">2.2 The Chips</a></li>
<li><a class="reference" href="#the-platform-directory" id="id12" name="id12">2.3 The Platform Directory</a></li>
<li><a class="reference" href="#the-tool-chain-make-system" id="id13" name="id13">2.4 The Tool-Chain (Make System)</a></li>
<li><a class="reference" href="#the-minimal-platform" id="id14" name="id14">2.5 The Minimal Platform</a></li>
</ul>
</li>
<li><a class="reference" href="#tool-chain" id="id15" name="id15">3. Tool Chain</a><ul>
<li><a class="reference" href="#compiling-using-nesc" id="id16" name="id16">3.1 Compiling using nesC</a></li>
<li><a class="reference" href="#the-make-system" id="id17" name="id17">3.2 The Make System</a><ul>
<li><a class="reference" href="#the-target-file" id="id18" name="id18">3.2.1 The .target file</a></li>
<li><a class="reference" href="#the-rules-file" id="id19" name="id19">3.2.2 The .rules file</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference" href="#the-platform" id="id20" name="id20">4. The Platform</a><ul>
<li><a class="reference" href="#platform-file" id="id21" name="id21">4.1 .platform file</a></li>
<li><a class="reference" href="#platformp-and-platformc" id="id22" name="id22">4.2 PlatformP and PlatformC</a><ul>
<li><a class="reference" href="#platformc" id="id23" name="id23">4.2.1 PlatformC</a></li>
<li><a class="reference" href="#platformp" id="id24" name="id24">4.2.1 PlatformP</a></li>
<li><a class="reference" href="#init-example-platformledsc" id="id25" name="id25">4.2.3 Init example: PlatformLedsC</a></li>
</ul>
</li>
<li><a class="reference" href="#platform-specific-code" id="id26" name="id26">3.3 Platform Specific Code</a><ul>
<li><a class="reference" href="#platform-headers" id="id27" name="id27">4.3.1 Platform Headers</a><ul>
<li><a class="reference" href="#hardware-h" id="id28" name="id28">hardware.h</a></li>
<li><a class="reference" href="#platform-message-h" id="id29" name="id29">platform_message.h</a></li>
</ul>
</li>
<li><a class="reference" href="#platform-specific-components" id="id30" name="id30">4.3.2 Platform Specific Components</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference" href="#id2" id="id31" name="id31">5. The chips</a><ul>
<li><a class="reference" href="#mcu-internals" id="id32" name="id32">5.1 MCU Internals</a><ul>
<li><a class="reference" href="#mcuxardware-h" id="id33" name="id33">5.1.1 mcuXardware.h</a></li>
<li><a class="reference" href="#mcusleepc" id="id34" name="id34">5.1.2 MCUSleepC</a></li>
</ul>
</li>
<li><a class="reference" href="#generalio" id="id35" name="id35">5.2 GeneralIO</a><ul>
<li><a class="reference" href="#example-msp430" id="id36" name="id36">5.2.1 Example MSP430</a></li>
</ul>
</li>
<li><a class="reference" href="#leds" id="id37" name="id37">5.3 LEDs</a><ul>
<li><a class="reference" href="#example-mica2dot" id="id38" name="id38">5.3.1 Example Mica2dot</a></li>
<li><a class="reference" href="#leds-implementation-discussion" id="id39" name="id39">5.3.2 LEDs implementation discussion</a></li>
</ul>
</li>
<li><a class="reference" href="#timers" id="id40" name="id40">5.4 Timers</a><ul>
<li><a class="reference" href="#timer-layers" id="id41" name="id41">5.4.1 Timer Layers</a><ul>
<li><a class="reference" href="#hpl" id="id42" name="id42">HPL</a></li>
<li><a class="reference" href="#hal" id="id43" name="id43">HAL</a></li>
<li><a class="reference" href="#hil" id="id44" name="id44">HIL</a></li>
</ul>
</li>
<li><a class="reference" href="#timer-implementation" id="id45" name="id45">5.4.2 Timer Implementation</a></li>
<li><a class="reference" href="#example-atmega128l" id="id46" name="id46">5.4.3 Example: ATMega128l</a></li>
<li><a class="reference" href="#id3" id="id47" name="id47">5.4.4 Example: MSP430</a></li>
<li><a class="reference" href="#example-pxa27x" id="id48" name="id48">5.4.5 Example: PXA27x</a></li>
<li><a class="reference" href="#timer-discussion" id="id49" name="id49">5.4.6 Timer Discussion</a></li>
</ul>
</li>
<li><a class="reference" href="#i-o-buses-uart-spi-i2c" id="id50" name="id50">5.5 I/O buses (UART, SPI, I2C)</a><ul>
<li><a class="reference" href="#serial-communication" id="id51" name="id51">5.5.1 Serial Communication</a></li>
<li><a class="reference" href="#i2c-spi" id="id52" name="id52">5.5.2 I2C, SPI</a><ul>
<li><a class="reference" href="#spibyte-spipacket" id="id53" name="id53">SpiByte, SpiPacket</a></li>
<li><a class="reference" href="#i2cpacket" id="id54" name="id54">I2CPacket</a></li>
</ul>
</li>
<li><a class="reference" href="#example" id="id55" name="id55">5.5.3 Example</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference" href="#authors" id="id56" name="id56">6. Authors</a></li>
<li><a class="reference" href="#citations" id="id57" name="id57">7. Citations</a></li>
</ul>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id6" id="tinyos-overview" name="tinyos-overview">1. TinyOS Overview</a></h1>
<p>Before describing the process of writing TinyOS platforms we will
briefly sum up the TinyOS ecosystem and the terminology required in
this TEP. To learn more visit the TinyOS website <a class="reference" href="http://www.tinyos.net">http://www.tinyos.net</a>.</p>
<p>A systems overview is depicted below. In this TEP we will primarily
concern our selves with the platform portion of figure and briefly
cover the tool chain. This involves writing the necessary drivers and
writing rules to pass the code to the TinyOS tool chain. We will not
cover sensor boards in this TEP refer to, see [<a class="reference" href="#tep109">TEP109</a>] for details.</p>
<pre class="literal-block">
+------------------------------------------+
|              Application                 |
+------------------------------------------+
+--------+   +----------+   +--------------+
| TinyOS | + | Platform | + | Sensor board |
+--------+   +----------+   +--------------+
                    |
                    V
           +-------------------+
           | TinyOS tool chain |
           +-------------------+
                    |
 Target platform    V
  +-------------------------------------+
  |  +-------+    +-----+    +-------+  |
  |  | Radio |----| MCU |----|Sensors|  |
  |  +-------+    +-----+    +-------+  |
  +-------------------------------------+
</pre>
<div class="section">
<h2><a class="toc-backref" href="#id7" id="tinyos-2-architecture" name="tinyos-2-architecture">1.1 TinyOS 2 architecture</a></h2>
<p>TinyOS 2.x is built on a tree-layered hardware abstraction
architecture (HAA)[<a class="reference" href="#tep2">TEP2</a>]. This architecture separates the code for
each platform into distinct layers:</p>
<blockquote>
<ol class="arabic simple">
<li>the Hardware Independent Layer (HIL)</li>
<li>the Hardware Adaptation Layer (HAL)</li>
<li>the Hardware Presentation Layer (HPL)</li>
</ol>
</blockquote>
<p>A platform is built from bottom up, starting with the HPL level,
building HAL and HIL layers on top. Platform independent applications
are written using HIL level interfaces, allowing them to move easily
from platform to platform. While applications can target a platform
specific HAL layer for finer control of hardware specific features,
this will could prohibit such an application from being easily
portable. An overview of the TinyOS 2 architecture is given in
[<a class="reference" href="#tos2-0view">tos2.0view</a>].</p>
<p>The requirements for the platform implementation is described in
TinyOS Enhancement Proposals (TEP). Each TEP covers a particular area
and specifies the recommendations within that area, some of which are
relevant for platforms. While no specific label or designation is
given to platforms adhering to the set of TEPs, [<a class="reference" href="#tep1">TEP1</a>] states:
&quot;Developers desiring to add code (or TEPs) to TinyOS SHOULD follow all
current BCPs (Best Current Practice)&quot;. At the time of writing no TEP
has been awarded this designation or been finalized and we will refer
to the drafts as they are.</p>
<p>This document will not go through each of the requirements, but merely
outline how to build a basic functional platform. For further
information see &quot;TinyOS 2.0 Overview&quot; [<a class="reference" href="#tos2-0view">tos2.0view</a>] or the TEP list on
the TinyOS website <a class="reference" href="http://www.tinyos.net">http://www.tinyos.net</a>.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id8" id="tinyos-contrib" name="tinyos-contrib">1.2 TinyOS Contrib</a></h2>
<p>The core of TinyOS is maintained by a set of working groups that
govern specific parts of the source code. New project can benefit from
the <em>contrib</em> section of TinyOS. This is a separate section of the
website and source repository maintained more loosely than the core of
TinyOS. It is intended for sharing code at an early stage or code that
may not gain the same popularity as the core.</p>
<p>New projects request a directory in this repository by following a
simple procedure on the <a class="reference" href="http://tinyos.cvs.sourceforge.net/*checkout*/tinyos/tinyos-2.x-contrib/contrib.html">TinyOS contrib web page</a></p>
<p>In contrib is a skeleton project <em>skel</em> that provides the most basic
framework for setting up a new platform, MCU, etc.</p>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id9" id="a-tinyos-platform" name="a-tinyos-platform">2. A TinyOS Platform</a></h1>
<p>A TinyOS platform provides the code and tool chain definitions that
enable an application writer to implement an application for a mote. A
platform in TinyOS exposes some or all of the features of a particular
physical mote device to TinyOS applications - it refers to an entire
system, not a single chip. In order to write programs for a device
using TinyOS a platform for that device must exist within TinyOS.</p>
<p>A physical platform is comprised of a set of chips. Similarly a TinyOS
platform is the collection of the components representing these chips
(corresponding to drivers) Common chips can be shared among platforms
and implementing a new platform could simply mean wiring existing
components in a new way. If the chips that make up the platform are
not supported by TinyOS implementing the new platform consists if
implementing components for those chips (much like implementing
drivers).</p>
<div class="section">
<h2><a class="toc-backref" href="#id10" id="a-new-platform" name="a-new-platform">2.1 A New Platform</a></h2>
<p>Platforms are discovered at compile time by the TinyOS tool
chain and a new platform placed in the search path will be discovered
automatically. In addition sensor boards can be defined in a very
similar manner, however we will not cover sensor boards, see [<a class="reference" href="#tep109">TEP109</a>]
for details. Defining a new platform boils down to 3 things:</p>
<blockquote>
<ol class="arabic simple">
<li>definitions of the chips that make up the platform,</li>
<li>platform definitions (combining chips to a platform) and,</li>
<li>the tool chain or make definitions.</li>
</ol>
</blockquote>
<p>The code for a TinyOS platform is spread out in a few locations of the
TinyOS tree depending based on those 3 categories. Below is an
overview of the locations and some of the files we will be needing in
the following (for further information see see &quot;Coding Conventions&quot;
[<a class="reference" href="#tep3">TEP3</a>] and the &quot;README&quot; files in each directory).</p>
<p>Through this TEP we will use the terms PlatformX and MCUX to denote
the new generic platform and MCU being created:</p>
<pre class="literal-block">
tos
 +--chips                            1. Chip definitions
 |    +--chipX
 +--platforms
 |    +--platformX                   2. Platform definitions
 |         +--PlatformP/PlatformC
 |         +--PlatformLeds              example component
 |         +--.platform
 |         +--hardware.h
 |         +--chips
 |              +--MCUX                 Platform specific features
 |              +--chipX
 +--sensorboards
 |    +--boardX
 |         +--.sensor
 +--support
      +--make                        3. Make definitions
           +--platformX.target          platformX make targets
           +--MCUX
                +--MCUX.rules           make rules for MCUX
                +--install.extra        additional target for MCUX
</pre>
<p>In the following we will briefly introduce each of the parts and
describe them in more detail in sections 2 through 4.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id11" id="the-chips" name="the-chips">2.2 The Chips</a></h2>
<p>Each of the chips that provide software accessible functionality must
have definitions present in the chips directory sensors, radios,
micro controllers (MCU) alike. Each chip is assigned a separate
directory under <tt class="docutils literal"><span class="pre">tos/chips</span></tt>. This directory contains chip specific
interfaces (HPL and HAL interfaces) and their implementations as well
as implementations of the hardware independent interface (HIL).</p>
<p>Some chips, MCUs in particular, contain distinct subsystems, such as
uart, timer, A/D converter, SPI, and so forth. These subsystems are
often put in a sub directory of their own within the chip-specific
directory.</p>
<p>If some feature of a chip is available or used only on a particular
platform, the platform directory can contain code that is specific to
this combination of chip and platform, say pin assignments, interrupt
assignments, etc. For example such additions would be placed in
<tt class="docutils literal"><span class="pre">tos/platforms/platformX/chips/chipX</span></tt> for PlatformX.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id12" id="the-platform-directory" name="the-platform-directory">2.3 The Platform Directory</a></h2>
<p>The platform is the piece of the puzzle that ties the components
corresponding to physical chips (drivers) together to form a
platform. The platform ties together the code that exposes the
features of the platform to TinyOS programs. In practise this is done
by i) including code for each of the chips and ii) by providing any
additional code that is specific to this particular platform.</p>
<p>A platform <em>PlatformX</em> would be placed in the directory
<tt class="docutils literal"><span class="pre">tos/platforms/platformX/</span></tt> and code for subsystems reside in further
sub directories. Also in this directory is the <tt class="docutils literal"><span class="pre">.platform</span></tt> file that
sets up include paths and more (see Section 3).</p>
<p>An empty platform with no code (null) is provided and serves as an
example for other platforms.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id13" id="the-tool-chain-make-system" name="the-tool-chain-make-system">2.4 The Tool-Chain (Make System)</a></h2>
<p>The build system for TinyOS is written using GNU Make <a class="footnote-reference" href="#make" id="id1" name="id1">[1]</a>. The
build system controls the process from pre-processing a TinyOS
application into a single C file and to pass this file to the
appropriate compiler and other tools. The make system is documented in
<tt class="docutils literal"><span class="pre">support/make/README</span></tt> and in TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>].</p>
<p>The make system is located in the <tt class="docutils literal"><span class="pre">support</span></tt> directory. This
directory contains a platform definition and Make rules to build an
application for this platform (see Section 2).</p>
<table class="docutils footnote" frame="void" id="make" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="make">[1]</a></td><td><a class="reference" href="http://www.gnu.org/software/make/">http://www.gnu.org/software/make/</a></td></tr>
</tbody>
</table>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id14" id="the-minimal-platform" name="the-minimal-platform">2.5 The Minimal Platform</a></h2>
<p>Before describing each of the subsystems, we will show a simple check
list. The absolute minimal TinyOS platform would have to provide the
following resources, given a <em>PlatformX</em> with <em>MCUX</em>:</p>
<ul class="simple">
<li>a platform directory <tt class="docutils literal"><span class="pre">tos/platform/PlatformX/</span></tt> with the following<ul>
<li>a platform definition (<em>.platform</em> file)</li>
<li>a <em>hardware.h</em> header</li>
</ul>
</li>
<li>a <em>platformX.target</em> in <tt class="docutils literal"><span class="pre">tos/support/make</span></tt></li>
<li>a <em>MCUX.rules</em> in <tt class="docutils literal"><span class="pre">tos/support/make/MCUX</span></tt></li>
<li>a <em>MCUX</em> directory in <tt class="docutils literal"><span class="pre">tos/chips/MCUX</span></tt>, containing<ul>
<li>a <em>McuSleepC</em> (must enable interrupts)</li>
<li>a <em>mcuxhardware.h</em> (defines <em>nesc_atomic_start</em>/<em>nesc_atomic_end</em>)</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id15" id="tool-chain" name="tool-chain">3. Tool Chain</a></h1>
<p>The major components in the tool chain of TinyOS are i) the compiler
and ii) the build system that uses the compiler to produce an
executable binary or hex file. The first is installed separately,
while the second is part of the TinyOS source code. The compile
process transforms a set of nesC files into a binary executable or hex
file. Involved in this process is set of separate tools that are
linked in a chain. We will briefly cover this chain in a moment, but a
detailed description is beyond the scope of this TEP.</p>
<p>The make system is split in two: a general part and a platform
specific part. Section 3.1 will introduce the general mechanism and
Section 3.2 will cover how to introduce a new platform in the tool
chain.</p>
<div class="section">
<h2><a class="toc-backref" href="#id16" id="compiling-using-nesc" name="compiling-using-nesc">3.1 Compiling using nesC</a></h2>
<p>The process of the build system is depicted below. This system feeds
the source code through the tools to produce an executable or hex file
for uploading to the platform. The nesC pre-compiler is split in two
tools ncc an nescc. These two tools are used to assemble nesC source
files into a single C file which is compiled using a regular C
compiler. This requires that a C compiler is available for a given
platform and that this compiler accepts the dialect produced by nesC.</p>
<pre class="literal-block">
  TinyOS
application
    |
    |
    V
+------+       +-----+        +---------+         +------------+
| ncc  | app.c |     | Binary |         | app.hex |            |
|  +   |------&gt;| GCC |-------&gt;| objdump |--------&gt;| programmer |
| nesC |       |     |        |         |         |            |
+------+       +-----+        +---------+         +------------+
                                                        |
                                                        |
                                                        V
                                                      Target
                                                     platform
</pre>
<p>The core TinyOS platforms are centered around GCC, this includes the
telos family, mica family and intelmote2. The nesC compiler expects
code resembling GCC C-dialect and also outputs code in GCC
C-dialect. The current TinyOS platforms are supported by GCC, but for
some processor architectures GCC is not available (e.g. Motorola HCS08,
Intel MCS51).</p>
<p>Porting to platforms that are GCC supported can benefit from the
existing tool flow, while porting to other platforms requires some
effort. A straight forward solution adopted for these platforms is to
post-process the C files produced by nesC to fit the needs of a
specific compiler, see TEP121 for an example of such a solution.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id17" id="the-make-system" name="the-make-system">3.2 The Make System</a></h2>
<p>TinyOS controls the build process using make. The global make file
searches certain locations to find make definitions for all available
platforms. In order to make a new platform available to the TinyOS
make system, a few files must be created in particular locations. These
files will be read by the global make system and exposed to the users
by make targets. Often the required rules are tied to a particular MCU
that is shared among several platforms and TinyOS leverages this fact
by creating a light-weight <em>.target</em> file pointing to the appropriate
rules in a <em>.rules</em> file. The make system is documented in
<tt class="docutils literal"><span class="pre">support/make/README</span></tt> and in TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>].</p>
<p>The make system looks for <em>.target</em> files in <tt class="docutils literal"><span class="pre">support/make</span></tt> and the
directories listed in the environment variable <tt class="docutils literal"><span class="pre">TOSMAKE_PATH</span></tt>. Each
of the files found contain make targets for one TinyOS platform. The
target files usually do not contain the rules to build the binary
files, but include the appropriate rules from a <em>.rules</em> file, located
in a sub directory for the appropriate MCU architecture (e.g. avr for
the ATMega128 used by Mica). In this way many platforms share the
build rules, but have different <em>.target</em> files. In addition <em>.extra</em>
targets can be used to define helper targets such as install or clean.</p>
<p>Setting up the make system, requires two steps (Section 3.2.1 gives an
example):</p>
<blockquote>
<ol class="arabic simple">
<li>Creating a <em>platformX.target</em> file that allows the make system to
discover the new platform. This file must contain a make rule with
the name of the platform. Further this target must depend on the
targets given in the variable <tt class="docutils literal"><span class="pre">BUILD_DEPS</span></tt> - this variable
contains the remainder of targets to be build during the build
process.</li>
<li>Creating a <em>.rules</em> file in a sub diretory of
<tt class="docutils literal"><span class="pre">support/make</span></tt>. Each file contain the actual target for
producing the binaries, hex files, etc. for one platform. They are
assembled in the <tt class="docutils literal"><span class="pre">BUILD_DEPS</span></tt> variable.</li>
</ol>
</blockquote>
<p>We will cover these two files next.</p>
<div class="section">
<h3><a class="toc-backref" href="#id18" id="the-target-file" name="the-target-file">3.2.1 The .target file</a></h3>
<p>As mentioned above TinyOS searches for targets in the <tt class="docutils literal"><span class="pre">support/make</span></tt>
directory of the TinyOS source code and in the directories listed in
the environment variable <tt class="docutils literal"><span class="pre">TOSMAKE_PATH</span></tt>. A <em>.target</em> file for the
platform must exist in one of these locations. The <em>.target</em> usually
only sets up variables related to this platform and provide a target
named after the platform, this target depend on other rules to build
the binaries. These rules are included by calling
<em>TOSMake_include_platform</em>. As an example the <tt class="docutils literal"><span class="pre">mica2.target</span></tt> is
listed below:</p>
<pre class="literal-block">
PLATFORM = mica2
SENSORBOARD ?= micasb
PROGRAMMER_PART ?= -dpart=ATmega128 --wr_fuse_e=ff
PFLAGS += -finline-limit=100000

AVR_FUSE_H ?= 0xd9

$(call TOSMake_include_platform,avr)

mica2: $(BUILD_DEPS)
        &#64;:
</pre>
<p>Pay attention to the call to <em>TOSMake_include_platform,avr</em> this call
includes <tt class="docutils literal"><span class="pre">.rules</span></tt> files in <tt class="docutils literal"><span class="pre">support/make</span></tt> or any sub directory of
<tt class="docutils literal"><span class="pre">TOSHMAKE_PATH</span></tt> named <em>avr</em>.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id19" id="the-rules-file" name="the-rules-file">3.2.2 The .rules file</a></h3>
<p>The <em>.rules</em> file contain the make rules for building the target
binary. If a MCU implementation already exists for a new platform,
simply pointing to this <em>.rules</em> from the corresponding <em>.target</em> is
sufficient. If not the <em>.rules</em> file must be built for a new MCU
architecture.</p>
<p><tt class="docutils literal"><span class="pre">TOSMake_include_platform</span></tt> expects a sub directory with a rule file
of the form <tt class="docutils literal"><span class="pre">avr/avr.rules</span></tt>. The call also includes additional
<em>.rules</em> and <em>.extra</em> files present in that sub directory.  See
<tt class="docutils literal"><span class="pre">support/make/README</span></tt> for details.</p>
<p>For example a simplified .rules file could look like this (from
<em>avr/avr.rules</em>):</p>
<pre class="literal-block">
...

    BUILD_DEPS = srec tosimage

srec: exe FORCE
        $(OBJCOPY) --output-target=srec $(MAIN_EXE) $(MAIN_SREC)

tosimage: ihex build_tosimage FORCE
        &#64;:

exe: builddir $(BUILD_EXTRA_DEPS) FORCE
        &#64;echo &quot;    compiling $(COMPONENT) to a $(PLATFORM) binary&quot;
        $(NCC) -o $(MAIN_EXE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS)
                  $(COMPONENT).nc $(LIBS) $(LDFLAGS)
...
</pre>
</div>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id20" id="the-platform" name="the-platform">4. The Platform</a></h1>
<p>A TinyOS platform is a collection of components corresponding to a
physical devices (a collection of drivers). A platform is constructed
by defining which components make up the platform and by providing any
additional platform specific components. The content of a platform is
not covered by a TEP at the time of writing and the following is based
on the available tutorials, <em>READMEs</em> and the current consensus.</p>
<p>The platform definitions for a <em>PlatformX</em> are located in
<tt class="docutils literal"><span class="pre">tos/platforms/platformX</span></tt> and contain 3 major elements:</p>
<blockquote>
<ol class="arabic simple">
<li>The <em>.platform</em> file containing include paths and other arguments
for nesC</li>
<li>Platform boot procedure: PlatformP/PlatformC</li>
<li>Platform specific code, including a header for hardware specific
funtions (hardware.h) and code that is specific to the combination
of chip and platform (e.g. pin assignments, modifications, etc.).</li>
</ol>
</blockquote>
<p>In the following we will describe each of these in more detail, below
is a depiction of a fictuous platform and the required definitions.</p>
<pre class="literal-block">
Platform:                           .platform
                                        include MCU driver
  +-------------------------+           include Radio driver
  |                         |           include Sensors driver
  | Chips:                  |
  |             +-------+   |       PlatformP
  |             | Radio |   |           Initialize MCU
  |             +--+----+   |           Initialize Sensor
  |   +-----+      |        |           Initialize Radio
  |   | MCU +------+        |
  |   +-----+      |        |       hardware.h
  |             +--+----+   |           Include MCU HW macros
  |             | Leds  |   |
  |             +-------+   |       HIL interfaces, eg:
  |                         |           PlatformLeds
  +-------------------------+
</pre>
<p>All the files we describe here must be found in a common directory
named after the platform; we call this a platform directory. This
directory must be found in the TinyOS tool chain search path for
example <tt class="docutils literal"><span class="pre">tos/platforms</span></tt> (or found in <tt class="docutils literal"><span class="pre">TOSHMAKE_PATH</span></tt> see Section
3.2.1). For example a platform named PlatformX could be placed in the
directory <tt class="docutils literal"><span class="pre">tos/platforms/platformX</span></tt>.</p>
<div class="section">
<h2><a class="toc-backref" href="#id21" id="platform-file" name="platform-file">4.1 .platform file</a></h2>
<p>All platform directories must carry a <tt class="docutils literal"><span class="pre">.platform</span></tt> file, this file
defines what makes up the platform. This file carries instructions for
the make system on where to locate the drivers for each of the
components of the platform. The definitions are read in a two step
process: the file is read by the ncc script that passes the
appropriate arguments to the nesC pre-processor[<a class="reference" href="#nescman">nescman</a>]. The
.platform file is written as a Perl script interpreted by ncc.</p>
<p>The file is documented in form of the README file in the platforms
directory (<em>tos/platforms</em>), and the source code of the ncc script
found in the TinyOS distribution. Valuable information can also be
found in [<a class="reference" href="#tep106">TEP106</a>], [<a class="reference" href="#tep109">TEP109</a>], TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>].</p>
<p>In addition to setting up include paths for nesC other arguments can
be passed on. In particular the components to be used for the
scheduler are selected with the '-fnesc-scheduler' command line
argument (see [<a class="reference" href="#tep106">TEP106</a>]). The include paths are passed on using the
'-I' command line argument covered in [<a class="reference" href="#tep109">TEP109</a>].</p>
<p>As an example, an abbreviated <em>.platform</em> file for the mica2 platform
looks like this:</p>
<pre class="literal-block">
push( &#64;includes, qw(
  %T/platforms/mica
  %T/platforms/mica2/chips/cc1000
  %T/chips/cc1000
  %T/chips/atm128
  %T/chips/atm128/adc
  %T/chips/atm128/pins
  %T/chips/atm128/spi
  %T/chips/atm128/timer
  %T/lib/timer
  %T/lib/serial
  %T/lib/power
) );

&#64;opts = qw(
  -gcc=avr-gcc
  -mmcu=atmega128
  -fnesc-target=avr
  -fnesc-no-debug
  -fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask
);
</pre>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id22" id="platformp-and-platformc" name="platformp-and-platformc">4.2 PlatformP and PlatformC</a></h2>
<p>The PlatformP and PlatformC components are responsible for booting
this platform to a usable state. In general this usually means things
like calibrating clock and initializing I/O pins. If this platform
requires that some devices are initialized in a particular order this
can be implemented in a platform dependent way here. The boot process
covered in [<a class="reference" href="#tep107">TEP107</a>].</p>
<p>Most hardware peripherals require an initialization procedure of some
sort. For most peripheral devices this procedure is only required when
the device is in use and can be left out if the device is
unused. TinyOS accomplishes this by providing a few initialization
call backs interfaces. When a given component is included it wires an
initialization procedure to one of these interfaces. In this way the
procedure will only be included when the component is included, this
process is known as auto wiring[<a class="reference" href="#tosprg">TOSPRG</a>].</p>
<p>The boot sequence calls two initialization interfaces in the following
order: <tt class="docutils literal"><span class="pre">PlatformC.Init</span></tt> and <tt class="docutils literal"><span class="pre">MainC.SoftwareInit</span></tt>.
<tt class="docutils literal"><span class="pre">PlatformC.Init</span></tt> must take care of initializing the hardware to an
operable state and initialization that has hidden dependencies must
occur here. Other components are initialized as part of
<tt class="docutils literal"><span class="pre">SoftwareInit</span></tt> and the orderign is determined at compile
time.</p>
<p>Common tasks in <tt class="docutils literal"><span class="pre">PlatformC.Init</span></tt> include clock calibration and IO
pins. However this component can be used to provide greater control of
the boot process if required. Consider for example that some component
which is initialized in SoftwareInit requires that some other
component has been initialized previously - lets say that the radio
must be initialized prior to the radio stack or that a component
prints a message to the UART during boot. How can this order be
ensured? One solution is to provide an additional initialization
handle prior to SoftwareInit and wire such procedures to this
handle. Below is an example from the Mica mote family using the
<tt class="docutils literal"><span class="pre">MoteInit</span></tt> interface.  Components that must be initialized early in
the boot process is wired to this interface. If greater level of
control is required this strategy can be trivially be expanded to
further levels of interfaces for example MoteInit1 being initialized
prior to MoteInit2, this strategy is chosen by the MSP430
implementation.</p>
<div class="section">
<h3><a class="toc-backref" href="#id23" id="platformc" name="platformc">4.2.1 PlatformC</a></h3>
<p>Below is depicted the PlatformC component from the Mica family of platforms.</p>
<pre class="literal-block">
#include &quot;hardware.h&quot;

configuration PlatformC {
  provides {
    interface Init;
    /**
     * Provides calibration information for other components.
     */
    interface Atm128Calibrate;
  }
  uses interface Init as SubInit;
} implementation {
  components PlatformP, MotePlatformC, MeasureClockC;

  Init = PlatformP;
  Atm128Calibrate = MeasureClockC;

  PlatformP.MeasureClock -&gt; MeasureClockC;
  PlatformP.MoteInit -&gt; MotePlatformC;
  MotePlatformC.SubInit = SubInit;
}
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id24" id="platformp" name="platformp">4.2.1 PlatformP</a></h3>
<p>Below is depicted the PlatformP component from the Mica family of platforms.</p>
<pre class="literal-block">
module PlatformP
{
  provides interface Init;
  uses interface Init as MoteInit;
  uses interface Init as MeasureClock;

}
implementation
{
  void power_init() {
     ...
  }

  command error_t Init.init()
  {
    error_t ok;

    ok = call MeasureClock.init();
    ok = ecombine(ok, call MoteInit.init());
    return ok;
  }
}
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id25" id="init-example-platformledsc" name="init-example-platformledsc">4.2.3 Init example: PlatformLedsC</a></h3>
<p>Below is an example from mica/PlatformLedsC.nc wiring to the platform
specific <em>MoteInit</em> interface.</p>
<pre class="literal-block">
configuration PlatformLedsC {
  provides interface GeneralIO as Led0;
...
  uses interface Init;
} implementation {
  components HplAtm128GeneralIOC as IO;
  components PlatformP;

  Init = PlatformP.MoteInit;
...
</pre>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id26" id="platform-specific-code" name="platform-specific-code">3.3 Platform Specific Code</a></h2>
<p>In addition to PlatformP/PlatformC the platform directory contain
additional code that is specific to this platform. First this could be
code that ties platform independent resources to particular instances
on this platform, second it could be code that is only relevant on
this particular platform (e.g. the clock rate of this platform). For
example the LEDs are a an example of the first: most platform have a
few LEDs, and the particular pin on this platform is tied to the
platform independent implementation using PlatformLedsC.</p>
<p>TinyOS requires that the header <tt class="docutils literal"><span class="pre">hardware.h</span></tt> is present while other
component can be named freely.</p>
<div class="section">
<h3><a class="toc-backref" href="#id27" id="platform-headers" name="platform-headers">4.3.1 Platform Headers</a></h3>
<p>TinyOS relies on a few C-header files being present for each
platform. These headers are then automatically included from the
respective parts of the TinyOS system. TinyOS expects that the
following files are present and that certain properties are defined in
them.</p>
<div class="section">
<h4><a class="toc-backref" href="#id28" id="hardware-h" name="hardware-h">hardware.h</a></h4>
<p>The <tt class="docutils literal"><span class="pre">hardware.h</span></tt> header file is included by <tt class="docutils literal"><span class="pre">tos/system/MainC.nc</span></tt>
and usually in turn includes a MCU specific header file, with a few
required macros (such as avr128hardware.h, see Section 5.1.1). The
header is documented in TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>]</p>
<p>In addition the hardware.h file can set flags that are not related to
the hardware in general, but to this platform (e.g. clock rate). Below
is a snippet from <tt class="docutils literal"><span class="pre">mica2/hardware.h</span></tt></p>
<pre class="literal-block">
#ifndef MHZ
/* Clock rate is ~8MHz except if specified by user
   (this value must be a power of 2, see MicaTimer.h and MeasureClockC.nc) */
#define MHZ 8
#endif

#include &lt;atm128hardware.h&gt;

enum {
  PLATFORM_BAUDRATE = 57600L
};
...
</pre>
</div>
<div class="section">
<h4><a class="toc-backref" href="#id29" id="platform-message-h" name="platform-message-h">platform_message.h</a></h4>
<p>As part of the TinyOS 2 message buffer abstraction[<a class="reference" href="#tep111">TEP111</a>], TinyOS
includes the header <em>platform_message.h</em> from the internal TinyOS
header <em>message.h</em>. This header is only strictly required for
platforms wishing to use the message_t abstraction - this is not
described further in this TEP, but is used widely throughout TinyOS
(See [<a class="reference" href="#tep111">TEP111</a>] for details). The is expected to define the structures:
<em>message_header_t</em>, <em>message_footer_t</em>, and <em>message_metadata_t</em> which
are used to fill out the generic <em>message_t</em> structure.</p>
<p>Below is an example from the <tt class="docutils literal"><span class="pre">mica2</span></tt> <em>platform_message.h</em></p>
<pre class="literal-block">
typedef union message_header {
  cc1000_header_t cc1k;
  serial_header_t serial;
} message_header_t;

typedef union message_footer {
  cc1000_footer_t cc1k;
} message_footer_t;

typedef union message_metadata {
  cc1000_metadata_t cc1k;
} message_metadata_t;
</pre>
</div>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id30" id="platform-specific-components" name="platform-specific-components">4.3.2 Platform Specific Components</a></h3>
<p>The code for platform dependent features also resides in the platform
directory. If the code can be tied to a particular chip it can be
placed in a separate directory below the <tt class="docutils literal"><span class="pre">chips</span></tt> directory. As an
example the following section of
<tt class="docutils literal"><span class="pre">micaz/chips/cc2420/HplCC2420PinsC.nc</span></tt> ties specific pins to general
names on the MicaZ platform.</p>
<pre class="literal-block">
configuration HplCC2420PinsC {
  provides {
    interface GeneralIO as CCA;
    interface GeneralIO as CSN;
    interface GeneralIO as FIFO;
    interface GeneralIO as FIFOP;
    interface GeneralIO as RSTN;
    interface GeneralIO as SFD;
    interface GeneralIO as VREN;
  }
}

implementation {

  components HplAtm128GeneralIOC as IO;

  CCA    = IO.PortD6;
  CSN    = IO.PortB0;
  FIFO   = IO.PortB7;
  FIFOP  = IO.PortE6;
  RSTN   = IO.PortA6;
  SFD    = IO.PortD4;
  VREN   = IO.PortA5;

}
</pre>
</div>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id31" id="id2" name="id2">5. The chips</a></h1>
<p>The functionality of each chip is provided by a set of one or more
interfaces and one or more components, in traditional terms this makes
up a driver. Each chip is assigned a sub directory in the the
<tt class="docutils literal"><span class="pre">tos/chips</span></tt> directory. All code that define the functionality of a
chip is located here regardless of the type of chip (MCU, radio,
etc.). In addition MCU's group the code related to separate sub
systems into further sub directories (e.g. <tt class="docutils literal"><span class="pre">tos/chips/atm128/timer</span></tt>).</p>
<p>In this section we will go trough some of the peripherals commonly
built into MCUs, but we will not go trough other chips such as sensors
or radio.</p>
<div class="section">
<h2><a class="toc-backref" href="#id32" id="mcu-internals" name="mcu-internals">5.1 MCU Internals</a></h2>
<p>Apart from the drivers for each of the peripheral units, a few
additional definitions are required for the internals of the MCU. This
includes i) atomic begin/end and ii) low power mode. The first is
defined in the header <em>hardware.h</em> and the latter component
<em>MCUSleepC</em>.</p>
<div class="section">
<h3><a class="toc-backref" href="#id33" id="mcuxardware-h" name="mcuxardware-h">5.1.1 mcuXardware.h</a></h3>
<p>Each architecture defines a set of required and useful macros in a
header filed named after the architecture (for example
<em>atm128hardware.h</em> for ATMega128). This header is then in turn
included from <em>hardware.h</em> in the platform directory (See Section
4.3.1).</p>
<p>A few of the macros are required by nesC code generation. nesC will
output code using these macros and they must be defined in advance,
other useful macros such as interrupt handlers on this particular
platform can be defined here as well. The required macros are:</p>
<blockquote>
<ul class="simple">
<li><em>__nesc_enable_interrupt</em> / <em>__nesc_disable_interrupt</em></li>
<li><em>__nesc_atomic_start</em> / <em>__nesc_atomic_end</em></li>
</ul>
</blockquote>
<p>Below is a few examples from <em>atm128hardware.h</em></p>
<pre class="literal-block">
/* We need slightly different defs than SIGNAL, INTERRUPT */
#define AVR_ATOMIC_HANDLER(signame) \
  void signame() __attribute__ ((signal)) &#64;atomic_hwevent() &#64;C()

#define AVR_NONATOMIC_HANDLER(signame) \
  void signame() __attribute__ ((interrupt)) &#64;hwevent() &#64;C()

...

inline void __nesc_enable_interrupt()  { sei(); }
inline void __nesc_disable_interrupt() { cli(); }

...

inline __nesc_atomic_t
__nesc_atomic_start(void) &#64;spontaneous()  {
    __nesc_atomic_t result = SREG;
    __nesc_disable_interrupt();
    asm volatile(&quot;&quot; : : : &quot;memory&quot;);
    return result;
}

/* Restores interrupt mask to original state. */
inline void
__nesc_atomic_end(__nesc_atomic_t original_SREG) &#64;spontaneous() {
  asm volatile(&quot;&quot; : : : &quot;memory&quot;);
  SREG = original_SREG;
}
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id34" id="mcusleepc" name="mcusleepc">5.1.2 MCUSleepC</a></h3>
<p>TinyOS manages the power state of the MCU through a few
interfaces. These interfaces allow components to signal how and when
this platform should enter low power mode. Each new MCU in TinyOS must
implement the <em>MCUSleepC</em> component that provide the <em>McuSleep</em> and
<em>McuPowerState</em> interfaces.</p>
<p>The TinyOS scheduler calls <em>McuSleep.sleep()</em> when it runs out of
tasks to start. The purpose of this function is to make the MCU enter
the appropriate sleep mode. The call to <em>McuSleep.sleep()</em> is made
from within an atomic section making it essential that sleep() enables
interrupts before entering sleep mode!  If the interrupts not enabled
prior to entering sleep mode the MCU will not be able to power back up.</p>
<p>A dummy MCU sleep component that does not enter sleep mode, but merely
switches interrupts on and off is shown below. This ensures that the
platform will not lock up even without proper sleep support.</p>
<pre class="literal-block">
#include &quot;hardware.h&quot;

module McuSleepC {
  provides interface McuSleep;
  provides interface McuPowerState;
  uses  interface McuPowerOverride;
} implementation {
  async command void McuSleep.sleep() {
    __nesc_enable_interrupt();
    // Enter sleep here
    __nesc_disable_interrupt();
  }

  async command void McuPowerState.update() { }
}
</pre>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id35" id="generalio" name="generalio">5.2 GeneralIO</a></h2>
<p>Virtually all micro controllers feature a set of input output (I/O)
pins.  The features of these pins is often configurable and often some
pins only support a subset of features. The HIL level interface for
TinyOS is described in [<a class="reference" href="#tep117">TEP117</a>] and uses two interface to describe
general purpose I/O pins common to many MCUs:</p>
<ul class="simple">
<li><strong>GeneralIO</strong>: Digital input/output. The GeneralIO interface
describes a digital pin with a state of either <em>clr</em> or <em>set</em>, the
pin must be capable of both input and output. Some MCUs provide pins
with different capabilities: more modes (e.g. an alternate
peripheral mode), less modes (e.g. only input) or a third
&quot;tri-state&quot; mode. Such chip specific additional features are not
supported. Some chips group a set of pins into &quot;ports&quot; that can be
read or written simultaneously, the HIL level interface does not
support reading or setting an entire port.</li>
<li><strong>GpioInterrupt</strong>: Edge triggered interrupts. GpioInterrupt support
a single pin providing an interrupt triggered on a rising or falling
edge. Pins capable of triggering on an input level or only
triggering on one edge is not supported.</li>
</ul>
<p>While these interfaces are aimed at the HIL level some platforms use
the GeneralIO and GpioInterrupt interface to represent the HPL level
(atm128 for example) and others platforms define their own interface
to capture the entire functionality (msp430, pxa27x for example).</p>
<p>[<a class="reference" href="#tep117">TEP117</a>] states that each platform must provide the general IO pins of
that platform through the <em>GeneralIO</em> interface and should do this
though the component <em>GeneralIOC</em>. It is however not clear how the
entire set of pins should be provided - this could be in the form of a
list of pins, group of pins, a generic component, etc.</p>
<p>The pin implementations are usually found in the <em>pins</em> sub directory
for a particular MCU (e.g. <em>msp430/pins</em> for MSP430 pin
implementation).</p>
<div class="section">
<h3><a class="toc-backref" href="#id36" id="example-msp430" name="example-msp430">5.2.1 Example MSP430</a></h3>
<p>The MSP430 implementation builds the platform independent pin
implementation as a stack of components starting with a platform
specific component for each pin.</p>
<pre class="literal-block">
           |  GeneralIO
+---------------------+
|      Msp430GpioC    |
+---------------------+
           |  HplMsp430GeneralIO
+---------------------+
| HplMsp430GeneralIOC |
+---------------------+
           |  HplMsp430GeneralIO
+---------------------+
| HplMsp430GeneralIOP |
+---------------------+
</pre>
<p>At the bottom the component <tt class="docutils literal"><span class="pre">HplMsp430GeneralIOP</span></tt> provides a general
implementation of one Msp430 pin using the <tt class="docutils literal"><span class="pre">HplMsp430GeneralIO</span></tt>
interface. The generic component <tt class="docutils literal"><span class="pre">HplMsp430GeneralIOP</span></tt> is then
instantiated for each pin by <tt class="docutils literal"><span class="pre">HplMsp430GeneralIOC</span></tt>.</p>
<pre class="literal-block">
interface HplMsp430GeneralIO {
  async command void set();
  async command void clr();
  async command void toggle();
  async command uint8_t getRaw();
  async command bool get();
  async command void makeInput();
  async command bool isInput();
  async command void makeOutput();
  async command bool isOutput();
  async command void selectModuleFunc();
  async command bool isModuleFunc();
  async command void selectIOFunc();
  async command bool isIOFunc();
}
</pre>
<p>This interface is implemented in the generic component
HplMsp430GeneralIOP (abbreviated):</p>
<pre class="literal-block">
 generic module HplMsp430GeneralIOP(uint8_t port_in_addr, ...)  {
   provides interface HplMsp430GeneralIO as IO;
 } implementation  {
   #define PORTx (*(volatile TYPE_PORT_OUT*)port_out_addr)

   async command void IO.set() { atomic PORTx |= (0x01 &lt;&lt; pin); }
   async command void IO.clr() { atomic PORTx &amp;= ~(0x01 &lt;&lt; pin); }
   async command void IO.toggle() { atomic PORTx ^= (0x01 &lt;&lt; pin); }

...
</pre>
<p>These are then instantiated from HplMsp430GeneralIOC (abbreviated):</p>
<pre class="literal-block">
configuration HplMsp430GeneralIOC {
  provides interface HplMsp430GeneralIO as Port10;
  provides interface HplMsp430GeneralIO as Port11;
...
} implementation {
  components
    new HplMsp430GeneralIOP(P1IN_, P1OUT_, P1DIR_, P1SEL_, 0) as P10,
    new HplMsp430GeneralIOP(P1IN_, P1OUT_, P1DIR_, P1SEL_, 1) as P11,
...
  Port10 = P10;
  Port11 = P11;
...
</pre>
<p>And finally these are transformed from the interface
HplMsp430GeneralIO to the platform independent GeneralIO using the
generic component Msp430GpioC (abbreviated):</p>
<pre class="literal-block">
generic module Msp430GpioC() {
  provides interface GeneralIO;
  uses interface HplMsp430GeneralIO as HplGeneralIO;
} implementation {
  async command void GeneralIO.set() { call HplGeneralIO.set(); }
  async command void GeneralIO.clr() { call HplGeneralIO.clr(); }
  async command void GeneralIO.toggle() { call HplGeneralIO.toggle(); }
...
</pre>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id37" id="leds" name="leds">5.3 LEDs</a></h2>
<p>Having a few leds on a platform is quite common and TinyOS supports
three leds in a platform independent manner. Three leds are provided
through the <em>LedsC</em> component regardless of the amount of leds
available on the platform. The LED implementation is not covered by a
TEP at the time of writing, but the general consensus between most
platforms seems to be to provide access to 3 LEDs through the
component <em>PlatformLedsC</em>. This component is then used by <em>LedC</em> and
<em>LedP</em> (from <tt class="docutils literal"><span class="pre">tos/system</span></tt>) to provide a platform independent Led
interface.</p>
<p>The PlatformLedsC implementation is found in the platform directory of
each platform (e.g. <em>tos/platforms/mica2</em> for mica2). The consensus is
as follows:</p>
<ul class="simple">
<li>Each platform provides the component PlatformLedsC</li>
<li>PlatformLedsC provides Led0, Led1, Led2 using the GeneralIO
interface. If the platform has less than 3 Leds these are wired to
the component NoPinC</li>
<li>PlatformLedsC <em>uses</em> the Init interface and usually it wired back to
an initialization in PlatformP - this way when LedC is included in
an application it will be initialized when PlatformP call this
interface</li>
</ul>
<div class="section">
<h3><a class="toc-backref" href="#id38" id="example-mica2dot" name="example-mica2dot">5.3.1 Example Mica2dot</a></h3>
<pre class="literal-block">
configuration PlatformLedsC
{
  provides interface GeneralIO as Led0;
  provides interface GeneralIO as Led1;
  provides interface GeneralIO as Led2;
  uses interface Init;
}
implementation  {
  components HplAtm128GeneralIOC as IO;
  components new NoPinC();
  components PlatformP;

  Init = PlatformP.MoteInit;

  Led0 = IO.PortA2;  // Pin A2 = Red LED
  Led1 = NoPinC;
  Led2 = NoPinC;
}
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id39" id="leds-implementation-discussion" name="leds-implementation-discussion">5.3.2 LEDs implementation discussion</a></h3>
<p>The Led interface described above is not specified in a TEP, though at
the time of writing most platforms seem to follow this pattern. Not
being covered by a TEP leads to a few uncertainties:</p>
<ul class="simple">
<li><em>PlatformLedsC</em> exports leds using the <em>GeneralIO</em> interface. The
intention is of course that a led is connected to a pin and this pin
is used to turn the led on. <em>LedC</em> uses this assumption to calls the
appropriate <em>makeOutput</em> and <em>set</em>/<em>clr</em> calls. However this might
not be the case - a led could be connected differently making the
semantics of, say <em>makeOutput</em> unclear. Furthermore it is assumed
that the set call turns the led on, while the actual pin might have
to be cleared (active low). And what is the semantics of <em>makeInput</em>
on a LED? Abstracting these differences into on/off, enable/disable
semantics would clear up the uncertainties.</li>
<li>Initializing the Leds is important - the Leds can consume power even
when turned off, if the corresponding pins are configured
inappropriately. Including the LedsC component initializes the Leds
as output when this component is used, if not they must be
initialized elsewhere (e.g. PlatformP). It would seem elegant to
group related code (e.g. one Leds component).</li>
<li>The interface does not provide a uniform way of accessing any
additional LEDs other than the 3 found on the Mica motes. While this
is inherently platform specific, having a common consensus would be
useful, say for example exporting an array of Led. In this way a
program requiring say 4 leds could be compiled if 4 leds are available.</li>
</ul>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id40" id="timers" name="timers">5.4 Timers</a></h2>
<p>The timer subsystem in TinyOS 2 is described in [<a class="reference" href="#tep102">TEP102</a>] the TEP
specifies interfaces at HAL and HIL levels that a platform must adhere
to. The timer does not cover the possible design choices at the HPL
level. The timers defined in this TEP are described in terms of
<em>width</em> of the underlying counters (e.g. 8, 16, 32 bit) and in the
tick period or frequency denoted <em>precision</em> (e.g. 10 kHz, 1 ms, 1
us). The timer subsystem is provided through a set of hardware
independent interfaces and a set of recommended configuration modules.
As such some features of a particular device may not be available in a
device independent manner.</p>
<p>The functionality commonly seen in MCU timer units is often split in 3
parts: control, timer/counter, capture/compare(trigger). Timer control
in is inherently platform specific and is not covered by a TEP. The
timer [<a class="reference" href="#tep102">TEP102</a>] covers timer/counter while capture/compare is covered
by [<a class="reference" href="#tep117">TEP117</a>]. From the TEPs it is not clear how capture/compare and
timer/counter relate to each other even though they are likely to
refer to the same time base. The calibration of the system clock is
often connected with the timer system and lives in the timer
directory, but it is not covered in [<a class="reference" href="#tep102">TEP102</a>].</p>
<p>The timer implementation for a given MCU is placed in the <em>timer</em> sub
directory of the directory for a given MCU
(e.g. <em>tos/chips/avr/timer</em>). Often clock initialization components
are placed in the same directory, but these are not covered by the
TEPs.</p>
<div class="section">
<h3><a class="toc-backref" href="#id41" id="timer-layers" name="timer-layers">5.4.1 Timer Layers</a></h3>
<p><a class="reference" href="#tep117">TEP117</a> follows the 3 layer architecture and separates the platform
dependent and independent abstractions. It poses not restrictions on
the HPL layer, but provides a suggested HAL layer and requirements at
the HIL level. It defines a set of interfaces and precisions that are
used at the HAL and HIL levels.</p>
<p>The common features of a timer are separated into a set of interfaces,
corresponding roughly to common features in MCU timer units. The
interfaces covered by the [<a class="reference" href="#tep102">TEP102</a>] are (capture from [<a class="reference" href="#tep117">TEP117</a>]):</p>
<ul class="simple">
<li><strong>BusyWait&lt;precision_tag,size_type&gt;</strong> Short synchronous delays</li>
<li><strong>Counter&lt;precision_tag, size_type&gt;</strong> Current time, and overflow events</li>
<li><strong>Alarm&lt;precision_tag,size_type&gt;</strong> Extend Counter with at a given time</li>
<li><strong>Timer&lt;precision_tag&gt;</strong> 32 bit current time, one shot and periodic events</li>
<li><strong>LocalTime&lt;precision_tag&gt;</strong> 32 bit current time without overflow</li>
<li><strong>GpioCapture</strong> 16 bit time value on an external event (precision unspecified)</li>
</ul>
<p>The precisions defined in [<a class="reference" href="#tep117">TEP117</a>] are defined as &quot;binary&quot; meaning
1024 parts of a second. Platforms must provide these precisions (if
possible) regardless of the underlying system frequency (i.e. this
could be a power of 10).</p>
<ul class="simple">
<li><strong>TMilli</strong> 1024 Hz (period 0.98 ms)</li>
<li><strong>TMicro</strong> 1048576 Hz (period 0.95 us)</li>
<li><strong>T32khz</strong> 32.768 kHz (period 30.5 us)</li>
</ul>
<div class="section">
<h4><a class="toc-backref" href="#id42" id="hpl" name="hpl">HPL</a></h4>
<p>The features of the underlying hardware timers are generally exposed
using one or more hardware specific interfaces. Many MCU provide a
rich a set of different timer units varying in timer width, frequency
and features.</p>
<p>Many MCUs provides features that are quite close to the features
described by the interfaces above. The HPL layer exposes these
features and the layers above utilize the available hardware and
virtualize the features if necessary.</p>
<p>Consider for example generating events at a specific time. Often a
timer unit has a single counter and a few compare registers that
generate interrupts. The counter and compare registers often translate
relative straightforward to Counter and Alarm interfaces.</p>
</div>
<div class="section">
<h4><a class="toc-backref" href="#id43" id="hal" name="hal">HAL</a></h4>
<p>Each platform should expose a hardware timer of precision P and width W
as Counter${P}${W}C, Alarm${P}${W}C(). For example an 8 bit, 32.768 kHz
timer should be exposed as Counter32khz8C and Alarm32khz8C</p>
<p>Alarm/Counters come in pairs and refer to a particular hardware unit,
while there is only one counter there is commonly multiple compare
registers. Alarm is a generic component and each instantiation must
provide an independent alarm allocating more Alarm components than
available compare register should provide a compile time error.</p>
</div>
<div class="section">
<h4><a class="toc-backref" href="#id44" id="hil" name="hil">HIL</a></h4>
<p>Each platform must expose the following components that provide
specific width and precision that are guaranteed to exist on TEP
compliant platforms.</p>
<blockquote>
<ul class="simple">
<li><strong>HilTimerMilliC</strong> A 32 bit Timer interface of TMilli precision</li>
<li><strong>BusyWaitMicroC</strong> A BusyWait interface of  TMicro precision</li>
</ul>
</blockquote>
</div>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id45" id="timer-implementation" name="timer-implementation">5.4.2 Timer Implementation</a></h3>
<p>Implementing the timers for TinyOS in short consists of utilizing the
available HW timer features to provide TinyOS style timers
interfaces. In general the approach taken by existing platforms is to
create a set of HPL level timer and control interfaces that export the
available hardware features and adapt these to specific precisions and
widths at the HAL level. However the specific HPL level design choices
differ from platform to platform.</p>
<p>For example one could export all timers as a simple list, a component
for each timer, a parameterised interface, etc. Similarly for the
control features this could be provided with the timer interfaces or
kept as a separate interface. In the following we will go through a
few examples and point out their differences.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id46" id="example-atmega128l" name="example-atmega128l">5.4.3 Example: ATMega128l</a></h3>
<p>The ATMega128l implementation (atm128) exports the system timers one
component each. Each component provide 4 interfaces - one for each of
the functions of the unit: timer, capture, compare and control. The
timer, capture, and compare interfaces are generic based on the width
(either 8 or 16 bit) while two separate control interfaces are
provided.</p>
<p>Depicted below is a diagram of how <tt class="docutils literal"><span class="pre">HplAtm128Timer1C</span></tt> could be stacked
to provide platform independent interfaces (not shown are
<tt class="docutils literal"><span class="pre">HplAtm128Timer0Async</span></tt>, <tt class="docutils literal"><span class="pre">HplAtm128Timer2</span></tt>, <tt class="docutils literal"><span class="pre">HplAtm128Timer3</span></tt>):</p>
<pre class="literal-block">
          +------------------------------------------------+
          |              HplAtm128Timer1C                  |
          +-----+-------------------+-----------------+----+
HplAtm128Capture|     HplAtm128Timer| HplAtm128Compare|
                |                   |                 |
     +----------+---------+         |                 |
     | Atm128GpioCaptureC |         |                 |
     +----------+---------+         |                 |
                |                 +-+-----------------+--+
     GpioCapture|                 |      Atm128AlarmC    |
                |                 +----------+-----------+
                |                       Alarm|
</pre>
<p>The hardware features is exported using 3 interfaces:
<tt class="docutils literal"><span class="pre">HplAtm128Timer</span></tt>, <tt class="docutils literal"><span class="pre">HplAtm128Compare</span></tt> and <tt class="docutils literal"><span class="pre">HplAtm128Capture</span></tt>.</p>
<pre class="literal-block">
interface HplAtm128Timer&lt;timer_size&gt;
{
  async command timer_size get();
  async command void       set( timer_size t );
  async event void overflow();
  async command void reset();
  async command void start();
...

interface HplAtm128Compare&lt;size_type&gt;
{
  async command size_type get();
  async command void set(size_type t);
  async event void fired();           //&lt;! Signalled on compare interrupt
  async command void reset();
...

interface HplAtm128Capture&lt;size_type&gt;
{
  async command size_type get();
  async command void      set(size_type t);
  async event void captured(size_type t);
  async command void reset();
</pre>
<dl class="docutils">
<dt>In addition to the timer related interfaces two control interfaces are</dt>
<dd>provided: 'HplAtm128TimerCtrl16' and 'HplAtm128TimerCtrl8' (below).</dd>
</dl>
<pre class="literal-block">
#include &lt;Atm128Timer.h&gt;

interface HplAtm128TimerCtrl8
{
  /// Timer control register: Direct access
  async command Atm128TimerControl_t getControl();
  async command void setControl( Atm128TimerControl_t control );

  /// Interrupt mask register: Direct access
  async command Atm128_TIMSK_t getInterruptMask();
  async command void setInterruptMask( Atm128_TIMSK_t mask);

  /// Interrupt flag register: Direct access
  async command Atm128_TIFR_t getInterruptFlag();
  async command void setInterruptFlag( Atm128_TIFR_t flags );
}
</pre>
<p>Each of the hardware timers are exported in one component for example
'HplAtm128Timer1P':</p>
<pre class="literal-block">
#include &lt;Atm128Timer.h&gt;

module HplAtm128Timer1P
{
  provides {
    // 16-bit Timers
    interface HplAtm128Timer&lt;uint16_t&gt;   as Timer;
    interface HplAtm128TimerCtrl16       as TimerCtrl;
    interface HplAtm128Capture&lt;uint16_t&gt; as Capture;
    interface HplAtm128Compare&lt;uint16_t&gt; as CompareA;
    interface HplAtm128Compare&lt;uint16_t&gt; as CompareB;
    interface HplAtm128Compare&lt;uint16_t&gt; as CompareC;
  }
  uses interface HplAtm128TimerCtrl8     as Timer0Ctrl;
}
implementation
{
  //=== Read the current timer value. ===================================
  async command uint16_t Timer.get() { return TCNT1; }

  //=== Set/clear the current timer value. ==============================
  async command void Timer.set(uint16_t t) { TCNT1 = t; }
...
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id47" id="id3" name="id3">5.4.4 Example: MSP430</a></h3>
<p>The MSP430 features two very similar (but not identical) timers. Both
timers are provided through the same interfaces in a way similar to
ATMega128l: 'Msp430Timer', 'Msp430Capture' 'Msp430Compare',
'Msp430TimerControl'. All timer interfaces (for both timers) are
accessed through the component Msp430TimerC.</p>
<p>The <tt class="docutils literal"><span class="pre">Msp430TimerControl</span></tt> is show below. It is slightly different
than the ATMega equivalent - notice that 'setControl' accepts a struct
with configuration parameters instead of setting these with a command
each.</p>
<pre class="literal-block">
#include &quot;Msp430Timer.h&quot;

interface Msp430TimerControl
{
  async command msp430_compare_control_t getControl();
  async command bool isInterruptPending();
  async command void clearPendingInterrupt();

  async command void setControl(msp430_compare_control_t control );
  async command void setControlAsCompare();
  async command void setControlAsCapture(uint8_t cm);

  async command void enableEvents();
  async command void disableEvents();
  async command bool areEventsEnabled();
}
</pre>
<p>Each timer is implemented through the generic component 'Msp430TimerP'
that is instantiated for each timer in 'Msp430TimerC':</p>
<pre class="literal-block">
configuration Msp430TimerC
{
  provides interface Msp430Timer as TimerA;
  provides interface Msp430TimerControl as ControlA0;
  provides interface Msp430TimerControl as ControlA1;
  provides interface Msp430TimerControl as ControlA2;
  provides interface Msp430Compare as CompareA0;
  provides interface Msp430Compare as CompareA1;
  provides interface Msp430Compare as CompareA2;
  provides interface Msp430Capture as CaptureA0;
  provides interface Msp430Capture as CaptureA1;
  provides interface Msp430Capture as CaptureA2;
...
}
implementation
{
  components new Msp430TimerP( TAIV_, TAR_, TACTL_, TAIFG, TACLR, TAIE,
               TASSEL0, TASSEL1, FALSE ) as Msp430TimerA
           , new Msp430TimerP( TBIV_, TBR_, TBCTL_, TBIFG, TBCLR, TBIE,
               TBSSEL0, TBSSEL1, TRUE ) as Msp430TimerB
           , new Msp430TimerCapComP( TACCTL0_, TACCR0_ ) as Msp430TimerA0
           , new Msp430TimerCapComP( TACCTL1_, TACCR1_ ) as Msp430TimerA1
           , new Msp430TimerCapComP( TACCTL2_, TACCR2_ ) as Msp430TimerA2
...
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id48" id="example-pxa27x" name="example-pxa27x">5.4.5 Example: PXA27x</a></h3>
<p>The PXA27x (XScale) platform provides a component for each of the
timers classes on the system. Each component provides a few interfaces
that exposes all features of that unit. Each interface combines timer
and control interface features. For example 'HplPXA27xOSTimerC'
provides 12 instances of the 'HplPXA27xOSTimer' interface and one
instace 'HplPXA27xOSTimerWatchdog'. Similarly for 'HplPXA27xSleep' and
'HplPXA27xWatchdog'.</p>
<pre class="literal-block">
interface HplPXA27xOSTimer
{
  async command void setOSCR(uint32_t val);
  async command uint32_t getOSCR();
...


  async event void fired();
}
</pre>
<p>All the OS timers are exported through HplPXA27xOSTimerC</p>
<pre class="literal-block">
configuration HplPXA27xOSTimerC {

  provides {
    interface Init;
    interface HplPXA27xOSTimer as OST0;
    interface HplPXA27xOSTimer as OST0M1;
    interface HplPXA27xOSTimer as OST0M2;
    interface HplPXA27xOSTimer as OST0M3;
...
implementation {
  components HplPXA27xOSTimerM, HplPXA27xInterruptM;

  Init = HplPXA27xOSTimerM;

  OST0 = HplPXA27xOSTimerM.PXA27xOST[0];
  OST0M1 = HplPXA27xOSTimerM.PXA27xOST[1];
  OST0M2 = HplPXA27xOSTimerM.PXA27xOST[2];
  OST0M3 = HplPXA27xOSTimerM.PXA27xOST[3];
...
</pre>
<p>These interfaces are further abstracted through 'HalPXA27xOSTimerMapC'
as a parameterised interface:</p>
<pre class="literal-block">
configuration HalPXA27xOSTimerMapC {
  provides {
    interface Init;
    interface HplPXA27xOSTimer as OSTChnl[uint8_t id];
  }
} implementation {
  components HplPXA27xOSTimerC;

  Init = HplPXA27xOSTimerC;

  OSTChnl[0] = HplPXA27xOSTimerC.OST4;
  OSTChnl[1] = HplPXA27xOSTimerC.OST5;
  OSTChnl[2] = HplPXA27xOSTimerC.OST6;
 ...
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id49" id="timer-discussion" name="timer-discussion">5.4.6 Timer Discussion</a></h3>
<p>While the TEP is clear on many points there are few that are left up
to the implementer.  The relation between timers and capture events is
unclear and covered in two TEPs. Capture refers to timers[<a class="reference" href="#tep102">TEP102</a>] but
the reverse is not clear[<a class="reference" href="#tep102">TEP102</a>]. This has a few implications for the
timer/capture relationship:</p>
<ul class="simple">
<li>Many devices feature multiple timers of the same width and
precision. It is not clear how this is provided. In particular how
this relates to a capture event - e.g. how does a capture event from
timer 2 relate to a time value from timer 1. Presumably TinyOS has
one system time based on a single timer which is used by all timer
capture interfaces and visualized if necessary.</li>
<li>The interfaces provide a an elegant way to expand a 16 bit timer to
a 32 bit interface. However this is not the case for capture events.</li>
</ul>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id50" id="i-o-buses-uart-spi-i2c" name="i-o-buses-uart-spi-i2c">5.5 I/O buses (UART, SPI, I2C)</a></h2>
<p>Most modern microprocessors provide a selection of standard I/O bus
units such as serial (UART or USART), I2C, SPI, etc. The drivers for
the available buses are usually put in a sub directory for the MCU
(e.g. <em>chip/atm128/spi</em> for SPI on ATMega128l).</p>
<p>There are a few TEP that cover different buses in TinyOS, and low
level serial communication:</p>
<ul class="simple">
<li><a class="reference" href="#tep113">TEP113</a> Serial Communication: Serial</li>
<li><a class="reference" href="#tep117">TEP117</a> Low-Level I/O: Serial, SPI, I2C</li>
</ul>
<p>On some hardware platforms a single I/O unit is shared among a number
of buses. The MSP430 for example implements SPI, I2C and USART in a
single USART unit that can only operate in one mode at a time. In such
cases the single hardware unit must be shared among the drivers.</p>
<div class="section">
<h3><a class="toc-backref" href="#id51" id="serial-communication" name="serial-communication">5.5.1 Serial Communication</a></h3>
<p>Serial communication in TinyOS 2.x is implemented as a serial
communications stack with a UART or USART at the bottom. The bottom
layer is covered in [<a class="reference" href="#tep113">TEP113</a>] and [<a class="reference" href="#tep117">TEP117</a>]. TEP117 states that each
platform must provide access to a serial port through the
'SerialByteComm' interface from the component UartC. However UartC is
not provided by any platforms at the time of writing. There seems to
be a consensus to build the component 'PlatformSerialC' providing the
'UartStream' and 'StdControl' interfaces. Either component will be
placed in the platform directory (e.g. <em>tos/platforms/mica2</em> for
mica2). The serial stack is built upon 'PlatformSerialC' and this
component will be required to take advantage of the serial stack.</p>
<p>[<a class="reference" href="#tep117">TEP117</a>] defines 'UartStream' and 'UartByte' to access the a UART
multiple bytes at a time and one byte at a time (synchronously), while
[<a class="reference" href="#tep113">TEP113</a>] defines 'UartByte' to send and receive one byte at a time
(asynchronously).</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id52" id="i2c-spi" name="i2c-spi">5.5.2 I2C, SPI</a></h3>
<p>SPI and I2C buses are provided through straightforward interfaces that
match the functionality of the buses closely.</p>
<div class="section">
<h4><a class="toc-backref" href="#id53" id="spibyte-spipacket" name="spibyte-spipacket">SpiByte, SpiPacket</a></h4>
<pre class="literal-block">
interface SpiByte {
  async command uint8_t write( uint8_t tx );
}
</pre>
<pre class="literal-block">
interface SpiPacket {
  async command error_t send( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len );
  async event void sendDone( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len,
                             error_t error );
}
</pre>
</div>
<div class="section">
<h4><a class="toc-backref" href="#id54" id="i2cpacket" name="i2cpacket">I2CPacket</a></h4>
<pre class="literal-block">
interface I2CPacket&lt;addr_size&gt; {
  async command error_t read(i2c_flags_t flags, uint16_t addr,
                             uint8_t length, uint8_t* data);
  async command error_t write(i2c_flags_t flags, uint16_t addr,
                              uint8_t length,  uint8_t* data);
  async event void readDone(error_t error, uint16_t addr,
                            uint8_t length, uint8_t* data);
  async event void writeDone(error_t error, uint16_t addr,
                             uint8_t length, uint8_t* data);
}
</pre>
</div>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id55" id="example" name="example">5.5.3 Example</a></h3>
<dl class="docutils">
<dt>..ATMega128</dt>
<dd>-&gt; does not provide SerialByteComm</dd>
<dt>..MSP430</dt>
<dd>-&gt; Uart1C provides SerialByteComm along with Init and StdControl
-&gt; sender det meste videre til Msp430Uart1C (som mangler Init!?!?)
Msp430Uart0C
-&gt; SerialByteComm, Msp430UartControl, Msp430UartConfigure, Resurce
-&gt; Sender videre til  Msp430Uart1P &amp; Msp430Usart1C
-&gt; Sender videre til HplMsp430Usart1C-&gt;HplMsp430Usart1P</dd>
<dt>..PXA27</dt>
<dd>Parametriseret m. HplPXA27xUARTP (Init &amp;&amp; HplPXA27xUART)
-&gt; init sÊtter en masse registre og enabler interrupt
HalPXA27xSerialP: HplPXA27xUART, Init, noget DMA noget</dd>
</dl>
</div>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id56" id="authors" name="authors">6. Authors</a></h1>
<div class="line-block">
<div class="line">Martin Leoold</div>
<div class="line">University of Copenhagen, Dept. of Computer Science</div>
<div class="line">Universitetsparken 1</div>
<div class="line">DK-2100 K¯benhavn ÿ</div>
<div class="line">Denmark</div>
<div class="line"><br /></div>
<div class="line">Phone +45 3532 1464</div>
<div class="line"><br /></div>
<div class="line">email - <a class="reference" href="mailto:leopold&#64;diku.dk">leopold&#64;diku.dk</a></div>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id57" id="citations" name="citations">7. Citations</a></h1>
<table class="docutils citation" frame="void" id="tep1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep1">[TEP1]</a></td><td>TEP 1: TEP Structure and Keywords
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep1.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep1.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep2">[TEP2]</a></td><td>TEP 2: Hardware Abstraction Architecture
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep2.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep2.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep3" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep3">[TEP3]</a></td><td>TEP 3: Coding Standard
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep3.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep3.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep102" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep102">[TEP102]</a></td><td>TEP 102: Timers
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep102.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep102.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep106" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep106">[TEP106]</a></td><td>TEP 106: Schedulers and Tasks
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep106.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep106.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep107" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep107">[TEP107]</a></td><td>TEP 107: TinyOS 2.x Boot Sequence
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep107.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep107.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep109" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep109">[TEP109]</a></td><td>TEP 109: Sensors and Sensor Boards
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep109.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep109.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep111" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep111">[TEP111]</a></td><td>TEP 111: message_t
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep111.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep111.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep113" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep113">[TEP113]</a></td><td>TEP 113: Serial Communication
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep113.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep113.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep117" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep117">[TEP117]</a></td><td>TEP 117: Low-Level I/O
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep117.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep117.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep121" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep121">[TEP121]</a></td><td>TEP 121: Towards TinyOS for 8051
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep121.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep121.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tosprg" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tosprg">[TOSPRG]</a></td><td>Philip Levis: TinyOS Programming
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/pdf/tinyos-programming.pdf">http://www.tinyos.net/tinyos-2.x/doc/pdf/tinyos-programming.pdf</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tos2-0view" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tos2-0view">[tos2.0view]</a></td><td>Philip Levis. &quot;TinyOS 2.0 Overview&quot; <em>Feb 8 2006</em>
&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/overview.html">http://www.tinyos.net/tinyos-2.x/doc/html/overview.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="nescman" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="nescman">[nescman]</a></td><td>David Gay, Philip Levis, David Culler, Eric Brewer. &quot;NesC 1.2 Language Reference Manual&quot; <em>August 2005</em></td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tut10" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tut10">[TUT10]</a></td><td><dl class="first docutils">
<dt>TinyOS 2 Tutorial Lesson 10</dt>
<dd>&lt;<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tutorial/lesson10.html">http://www.tinyos.net/tinyos-2.x/doc/html/tutorial/lesson10.html</a>&gt;</dd>
</dl>
<p class="last">LocalWords:  TinyOS TEP TEPs nesC</p>
</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
